﻿using System;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using QQ2564874169.Json;
using QQ2564874169.MessageQueue;
using Tests.MessageQueue.Mocks;

namespace Tests.MessageQueue
{
    [TestClass]
    public class 实体消息
    {
        [TestMethod]
        public void 普通的接收Model()
        {
            var model = new TestModel
            {
                Id = Guid.NewGuid(),
                Name = Guid.NewGuid().ToString()
            };
            TestModel conModel = null;
            string jsonModel = null;
            var count = 0;
            var count2 = 0;
            TestService.OnConsume += (s, e) =>
            {
                count++;
                conModel = e;
            };
            TestService2.OnConsume += (s, e) =>
            {
                count2++;
                jsonModel = e;
            };
            var subscr = new SubscribeModelFromMq(() => new MockResolver(), (t, s) => JsonHelper.JsonTo(s, t));
            subscr.LoadService(typeof(TestService), typeof(TestService2));
            subscr.Start();
            var publish = new PublishModelToMq(obj => JsonHelper.ToJson(obj));
            publish.ImmediatelyPublish(model);
            Task.Delay(1000).Wait();
            subscr.Stop();
            
            Assert.IsNotNull(conModel);
            Assert.AreEqual(1, count);
            Assert.AreEqual(model.Id, conModel.Id);
            Assert.AreEqual(model.Name, conModel.Name);
            Assert.AreEqual(1, count2);
            Assert.AreEqual(JsonHelper.ToJson(model), jsonModel);
        }

        [TestMethod]
        public void TestAttr()
        {
            var attr = typeof(TestModel).GetCustomAttributes<ToMq>();
            Assert.IsTrue(attr.Any());
        }
    }

    public class TestToMq : ToMq
    {
        private IMqSubscriber _subscriber;
        private IMqPublisher _publisher;

        public override IMqPublisher Publisher => _publisher ?? (_publisher = new AppMqPublisher());
        public override IMqSubscriber Subscriber => _subscriber ?? (_subscriber = new AppMqSubscriber());
    }

    public class TestToMq2 : ToMq
    {
        private IMqSubscriber _subscriber;
        private IMqPublisher _publisher;

        public override IMqPublisher Publisher => _publisher ?? (_publisher = new AppMqPublisher());
        public override IMqSubscriber Subscriber => _subscriber ?? (_subscriber = new AppMqSubscriber());
    }

    [TestToMq]
    [TestToMq2]
    public class TestModel
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
    }

    public class TestService : IConsumeModel<TestToMq, TestModel>
    {
        public static event EventHandler<TestModel> OnConsume;

        public void Consume(TestModel model)
        {
            OnConsume?.Invoke(this, model);
        }
    }

    public class TestService2 : IConsumeModel<TestToMq2>
    {
        public static event EventHandler<string> OnConsume;

        public void Consume(string message)
        {
            OnConsume?.Invoke(this, message);
        }
    }
}
